home *** CD-ROM | disk | FTP | other *** search
- { Can handle only up to 16384 faces objects
- (C) X-wizard/DCC VR LABS
- The chevy is converted by EMS version of this converter, }
-
- {usage: 3DSC object.3ds object.dcc SCALE (smaller->bigger object}
- {example: 3DSC object.3ds object.dcc 50}
-
- uses crt;
- type vertex=record
- x:integer;
- y:integer;
- z:integer;
- end;
- cords=record
- x:integer;
- y:integer;
- z:integer;
- xy :integer;
- end;
- face=record
- a:integer;
- b:integer;
- c:integer;
- n:vertex;
- vn:array[1..3] of vertex;
- fxy :integer;
- end;
- vlist=array[0..($fffe div 4)-1] of ^cords;
- flist=array[0..($fffe div 4)-1] of ^face;
- object3d=record
- faces:word;
- vertices:word;
- face:^flist;
- vert:^vlist;
- end;
-
- var obj:array[1..1000] of ^object3d;
- procedure calcnormals(var list:flist;var vl:vlist;fcount:word);
- var f,f1:word;
- a,b,c:word;
- fc:array[1..3] of word;
- a1,b1,c1:word;
- x,y,z:array[1..3] of real;
- tv:array[1..3] of vertex;
- i,j,k,d:real;
- begin;
- {surface normals}
- clrscr;
- for F:=0 to fcount-1 do
- begin;
- gotoxy(1,1);
- writelN('Calculating surface normals for face: ',f:5);
- a:=list[f]^.a;
- b:=list[f]^.b;
- c:=list[f]^.c;
- x[1]:=vl[a]^.x / 256;
- y[1]:=vl[a]^.y / 256;
- z[1]:=vl[a]^.z / 256;
- x[2]:=vl[b]^.x / 256;
- y[2]:=vl[b]^.y / 256;
- z[2]:=vl[b]^.z / 256;
- x[3]:=vl[c]^.x / 256;
- y[3]:=vl[c]^.y / 256;
- z[3]:=vl[c]^.z / 256;
- i:=(((Y[2] - y[1]) * (Z[3] - Z[1])) - ((Z[2] - Z[1]) * (Y[3] - Y[1])));
- j:=(((Z[2] - Z[1]) * (X[3] - X[1])) - ((X[2] - X[1]) * (Z[3] - Z[1])));
- k:=(((X[2] - X[1]) * (Y[3] - Y[1])) - ((Y[2] - Y[1]) * (X[3] - X[1])));
- d:= sqrt(((i * i) + (j * j)+ (k * k)));
- if d=0 then d:=1;
- i:= (i / d);
- j:= (j / d);
- k:= (k / d);
- list[f]^.n.x:=round(i* 256);
- list[f]^.n.y:=round(j* 256);
- list[f]^.n.z:=round(k* 256);
- end;
- {vertex normals}
- for F:=0 to fcount-1 do
- begin;
- fc[1]:=0;
- fc[2]:=0;
- fc[3]:=0;
- a:=list[f]^.a;
- b:=list[f]^.b;
- c:=list[f]^.c;
- tv[1].x:=0;
- tv[1].y:=0;
- tv[1].z:=0;
- tv[2].x:=0;
- tv[2].y:=0;
- tv[2].z:=0;
- tv[3].x:=0;
- tv[3].y:=0;
- tv[3].z:=0;
- for F1:=0 to fcount-1 do
- begin;
- a1:=list[f1]^.a;
- b1:=list[f1]^.b;
- c1:=list[f1]^.c;
- if (a=a1)or(a=b1)or(a=c1) then begin;
- tv[1].x:=tv[1].x+list[f1]^.n.x;
- tv[1].y:=tv[1].y+list[f1]^.n.y;
- tv[1].z:=tv[1].z+list[f1]^.n.z;
- fc[1]:=fc[1]+1;
- end;
- if (b=a1)or(b=b1)or(b=c1) then begin;
- tv[2].x:=tv[2].x+list[f1]^.n.x;
- tv[2].y:=tv[2].y+list[f1]^.n.y;
- tv[2].z:=tv[2].z+list[f1]^.n.z;
- fc[2]:=fc[2]+1;
- end;
- if (c=a1)or(c=b1)or(c=c1) then begin;
- tv[3].x:=tv[3].x+list[f1]^.n.x;
- tv[3].y:=tv[3].y+list[f1]^.n.y;
- tv[3].z:=tv[3].z+list[f1]^.n.z;
- fc[3]:=fc[3]+1;
- end;
- end;
-
- tv[1].x:=tv[1].x div fc[1];
- tv[1].y:=tv[1].y div fc[1];
- tv[1].z:=tv[1].z div fc[1];
- list[f]^.vn[1].x:=tv[1].x;
- list[f]^.vn[1].y:=tv[1].y;
- list[f]^.vn[1].z:=tv[1].z;
- tv[2].x:=tv[2].x div fc[2];
- tv[2].y:=tv[2].y div fc[2];
- tv[2].z:=tv[2].z div fc[2];
- list[f]^.vn[2].x:=tv[2].x;
- list[f]^.vn[2].y:=tv[2].y;
- list[f]^.vn[2].z:=tv[2].z;
- tv[3].x:=tv[3].x div fc[3];
- tv[3].y:=tv[3].y div fc[3];
- tv[3].z:=tv[3].z div fc[3];
- list[f]^.vn[3].x:=tv[3].x;
- list[f]^.vn[3].y:=tv[3].y;
- list[f]^.vn[3].z:=tv[3].z;
- list[f]^.fxy:=0;
- gotoxy(1,1);
- writelN('Calculated vertex normals for face: ',f:5);
- writelN('Vertex normal a.x:',tv[1].x:10);
- writelN('Vertex normal a.y:',tv[1].y:10);
- writelN('Vertex normal a.z:',tv[1].z:10);
- writelN('Vertex normal b.x:',tv[2].x:10);
- writelN('Vertex normal b.y:',tv[2].y:10);
- writelN('Vertex normal b.z:',tv[2].z:10);
- writelN('Vertex normal c.x:',tv[3].x:10);
- writelN('Vertex normal c.y:',tv[3].y:10);
- writelN('Vertex normal c.z:',tv[3].z:10);
- end;
- end;
- procedure center(vcount:WORD;var list:vlist);
- var vert:word;
- cp,mx,mi:vertex;
- begin;
- mx.x:=list[0]^.x;
- mx.y:=list[0]^.y;
- mx.z:=list[0]^.z;
- mi.x:=list[0]^.x;
- mi.y:=list[0]^.y;
- mi.z:=list[0]^.z;
- for vert:=0 to vcount-1 do
- begin;
- if list[vert]^.x>mx.x then mx.x:=list[vert]^.x;
- if list[vert]^.y>mx.y then mx.y:=list[vert]^.y;
- if list[vert]^.z>mx.z then mx.z:=list[vert]^.z;
- if list[vert]^.x<mi.x then mi.x:=list[vert]^.x;
- if list[vert]^.y<mi.y then mi.y:=list[vert]^.y;
- if list[vert]^.z<mi.z then mi.z:=list[vert]^.z;
- end;
- cp.x:=(mi.x+mx.x)div 2;
- cp.y:=(mi.y+mx.y)div 2;
- cp.z:=(mi.z+mx.z)div 2;
- for vert:=0 to vcount-1 do
- begin;
- list[vert]^.x:=list[vert]^.x-cp.x;
- list[vert]^.y:=list[vert]^.y-cp.y;
- list[vert]^.z:=list[vert]^.z-cp.z;
- list[vert]^.xy:=round((list[vert]^.x * list[vert]^.y)/256);
- {DONT USE XY COZ PASCAL SUCKS!!!!!!!!!!!LIKE HELLL}
- end;
- end;
- procedure saveDCC(fname:string;start,eend:word);
- var f:file;
- nmb,d:word;
- begin;
- assign(f,fname);
- rewrite(f,1);
- for nmb:=start to eend do
- begin;
- blockwrite(f,obj[nmb]^.faces,sizeof(obj[nmb]^.faces));
- blockwrite(f,obj[nmb]^.vertices,sizeof(obj[nmb]^.vertices));
- for d:=0 to obj[nmb]^.faces-1 do
- begin;
- blockwrite(f,obj[nmb]^.face^[d]^,sizeof(obj[nmb]^.face^[d]^));
- end;
- for d:=0 to obj[nmb]^.vertices-1 do
- begin;
- blockwrite(f,obj[nmb]^.vert^[d]^,sizeof(obj[nmb]^.vert^[d]^));
- end;
- end;
- close(f);
- end;
-
- procedure readword(var f:file;var str:string);
- var ch:byte;
- begin;
- str:='';
- repeat;
- blockread(f,ch,1);
- if ch<>0 then str:=str+chr(ch);
- until ch=0;
- end;
-
- var f:file;
- objcnt:word;
- chunkid:word;
- filesize,nextchunk:longint;
- name:string;
- skip:boolean;
- xtra,a,b,c,v,faces,vertices:word;
- scale:real;
- e:integer;
- rx,ry,rz:single;
- begin;
- {scale:=30;}
- val(paramstr(3),scale,e);
- if e<>0 then begin;
- writeln('error');
- end;
- assign(f,paramstr(1){'..\dcc.3ds'});
- reset(f,1);
- blockreaD(f,chunkid,2);
- blockreaD(f,filesize,4);
- if chunkid<>$4d4d then begin;
- writeln('not a 3DS file....');
- close(f);
- halt;
- end;
- objcnt:=0;
- repeat
- blockreaD(f,chunkid,2);
- blockreaD(f,nextchunk,4);
- skip:=true;
- if chunkid=$3d3d then begin;
- blockreaD(f,chunkid,2);
- blockreaD(f,nextchunk,4);
- skip:=true;
- end;
- if chunkid=$4000 then begin;
- readword(f,name);
- writeln('Obj name:',name);
- objcnt:=objcnt+1;
- new(obj[objcnt]);
- skip:=false;
- end;
- if chunkid=$4600 then begin;
- writeln('A light skipped....');
- dispose(obj[objcnt]);
- objcnt:=objcnt-1;
- end;
- if chunkid=$4700 then begin;
- writeln('A camera skipped....');
- dispose(obj[objcnt]);
- objcnt:=objcnt-1;
- end;
- if chunkid=$4100 then begin;
- writeln('A true object loading mesh...');
- skip:=false;
- end;
- if chunkid=$4110 then begin;
- {vertex list}
- blockread(f,vertices,2);
- obj[objcnt]^.vertices:=vertices;
- getmem(obj[objcnt]^.vert,vertices*4{sizeof(cords)});
- clrscr;
- for v:=0 to vertices-1 do
- begin;
- new(obj[objcnt]^.vert^[v]);
- blockread(f,rx,4);
- blockread(f,ry,4);
- blockread(f,rz,4);
- {X:0.253727 Y:-0.000012 Z:-20.659882}
- rx:=rx/scale;
- ry:=ry/scale;
- rz:=rz/scale;
- obj[objcnt]^.vert^[v]^.x:=round(rx*256);
- obj[objcnt]^.vert^[v]^.y:=round(ry*256);
- obj[objcnt]^.vert^[v]^.z:=round(rz*256);
- gotoxy(1,1);
- writeln('vertices:',vertices);
- writeln('vertex x:',obj[objcnt]^.vert^[v]^.x);
- writeln('vertex y:',obj[objcnt]^.vert^[v]^.y);
- writeln('vertex z:',obj[objcnt]^.vert^[v]^.z);
- end;
- skip:=false;
- end;
- if chunkid=$4120 then begin;
- {face list}
- blockread(f,faces,2);
- obj[objcnt]^.faces:=faces;
- getmem(obj[objcnt]^.face,faces*4{sizeof(face)});
- clrscr;
- for v:=0 to faces-1 do
- begin;
- new(obj[objcnt]^.face^[v]);
- blockread(f,c,2);
- blockread(f,b,2);
- blockread(f,a,2);
- blockread(f,xtra,2);
-
- obj[objcnt]^.face^[v]^.a:=a;
- obj[objcnt]^.face^[v]^.b:=b;
- obj[objcnt]^.face^[v]^.c:=c;
- gotoxy(1,1);
- writeln('faces:',faces:8);
- writeln('face a:',obj[objcnt]^.face^[v]^.a:8);
- writeln('face b:',obj[objcnt]^.face^[v]^.b:8);
- writeln('face c:',obj[objcnt]^.face^[v]^.c:8);
- end;
- skip:=false;
- end;
- if skip then begin;
- seek(f,filepos(f)+nextchunk-6);
- end;
- until eof(f);
- close(f);
- if objcnt=0 then begin;
- writeln('No objects ....');
- halt;
- end;
- for v:=1 to objcnt do
- begin;
- center(obj[v]^.vertices,obj[v]^.vert^);
- calcnormals(obj[v]^.face^,obj[v]^.vert^,obj[v]^.faces);
- end;
- savedcc(paramstr(2){'ufo3d.dcc'},1,objcnt);
- writeln(objcnt);
- end.
-